home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 March / Macworld (1998-03) (Disk 1).dmg / Shareware World / Info / For Developers / GhostScript 5.10 / MacGS-510 / doc / c-style.txt < prev    next >
Text File  |  1997-08-04  |  11KB  |  330 lines

  1.    Copyright (C) 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17.  
  18. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  19.  
  20. This file, c-style.txt, describes Aladdin's C coding guidelines.
  21.  
  22. For an overview of Ghostscript and a list of the documentation files, see
  23. README.
  24.  
  25. Generalities
  26. ============
  27.  
  28. All the rules below are meant to produce code that is easy to read.  If you
  29. find a rule getting in your way or producing ugly-looking results once in a
  30. while, it's OK to break it.
  31.  
  32. Indentation
  33. -----------
  34.  
  35. Tab stops are set every 8 columns.  However, tabs are not equivalent to
  36. logical nesting levels for C code: see below for details.
  37.  
  38. File layout
  39. -----------
  40.  
  41. Every code file should start with comments containing a copyright notice,
  42. the name of the file, and a half-to-one-line summary of what the file
  43. contains.  If you create a file by copying the boilerplate from another
  44. file, make sure to edit the copyright year and the file name.
  45.  
  46. C code
  47. ======
  48.  
  49. makefiles
  50. ---------
  51.  
  52. For each #include "xxx.h", make sure there is a dependency on $(xxx_h) in
  53. the makefile.  If xxx ends with a _, this rule still holds: e.g., #include
  54. "math_.h" should create a dependency on $(math__h) (two underscores).
  55.  
  56. List the dependencies bottom-to-top, like the #includes themselves; within
  57. each level, list them alphabetically.  Also do this with the #includes
  58. themselves whenever possible (but sometimes there are inter-header
  59. dependencies that require bending this).
  60.  
  61. Headers
  62. -------
  63.  
  64. In header files, always use the following to prevent double inclusion:
  65.  
  66.     << copyright notice, file name, 1-line file description >>
  67.  
  68.     #ifndef <filename>_INCLUDED
  69.     #  define <filename>_INCLUDED
  70.  
  71.     << contents of file >>
  72.  
  73.     #endif                 /* <filename>_INCLUDED */
  74.  
  75. The header file is the first place that a reader will go to find out
  76. information about procedures, structures, constants, etc.  Make sure that
  77. every procedure and structure has a comment that says what it does.  Divide
  78. procedures into meaningful groups set off by some distinguished form of
  79. comment.
  80.  
  81. #include lists
  82. --------------
  83.  
  84. List #includes from "bottom" to "top", i.e., in the following order:
  85.     System includes ("xxx_.h")
  86.     g*.h
  87.     s*.h
  88.     pl*.h
  89.     p[cg]*.h
  90.  
  91. Indentation
  92. -----------
  93.  
  94. Put the first indentation point at the first tab stop; thereafter, each
  95. level of logical nesting indents by an additional 4 columns.  Proceed as
  96. follows:
  97.  
  98.     { ... in-line compound statement ...
  99.       ... (indented +2 columns)
  100.     }
  101.     ... construct requiring subordinate code ...
  102.       ... subordinate simple statement ... (indented +2 columns)
  103.     ... construct requiring subordinate code ...
  104.       { ... subordinate code ...
  105.         ... (indented +4 columns)
  106.       }
  107.  
  108. Or you can do this if you prefer:
  109.  
  110.     {
  111.       ... in-line compound statement ...
  112.     }
  113.     ... construct requiring subordinate code ...
  114.       ... subordinate simple statement ...
  115.     ... construct requiring subordinate code ...
  116.       {
  117.         ... subordinate code ...
  118.       }
  119.  
  120. But not this:
  121.  
  122.     if ... {
  123.       ... subordinate code ...
  124.     } else {
  125.       ... subordinate code ...
  126.     }
  127.  
  128. Spaces
  129. ------
  130.  
  131. Do put a space:
  132.     - after every comma and semicolon, unless it ends a line;
  133.     - around every binary operator, although you can omit the spaces
  134.     around the innermost operator in a nested expression if you like;
  135.     - on both sides of the the parentheses of an if, for, or while.
  136.  
  137. Don't put a space:
  138.     - at the end of a line;
  139.     - before a comma or semicolon;
  140.     - after unary prefix operators;
  141.     - before the parenthesis of a macro or procedure call.
  142.  
  143. Parentheses
  144. -----------
  145.  
  146. There are just a few places where parentheses are important:
  147.  
  148.     - In expressions that mix && and ||, around the inner
  149.     subexpressions, even if not required by precedence, e.g.,
  150.         (xx && yy) || zz
  151.  
  152.     - In expressions that mix &, |, and/or shifts, especially if
  153.     mixing these with other operators, around the inner subexpressions
  154.     similarly, e.g.,
  155.         (x << 3) | (y >> 5)
  156.  
  157.     - In macro definitions, around every use of an argument that
  158.     logically could be an expression, e.g.,
  159.         ((x) * (x) + (y) * (y))
  160.  
  161. Anywhere else, given the choice, use fewer parentheses.
  162.  
  163. For stylistic consistency with the existing Ghostscript code, put
  164. parentheses around conditional expressions, even if they aren't
  165. syntactically required, unless you really dislike doing this.  Note that the
  166. parentheses should go around the entire expression, not the condition: e.g.,
  167. instead of
  168.  
  169.     hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, 
  170.                    (pgls->g.pen_down) ? gs_lineto : gs_moveto);
  171.  
  172. use
  173.  
  174.     hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, 
  175.                    (pgls->g.pen_down ? gs_lineto : gs_moveto));
  176.  
  177. Types
  178. -----
  179.  
  180. Use 'private' instead of 'static' for constructs (procedures and variables)
  181. declared at the outermost scope.  This allows making such constructs either
  182. visible or invisible to profilers with a single changed #define.
  183.  
  184. Use const wherever possible and appropriate.
  185.  
  186. If you find yourself wanting to use void *, try to find an alternative using
  187. unions or (in the case of super- and subclasses) casts, unless you're
  188. writing something like a memory manager that really treats memory as opaque.
  189.  
  190. Use anonymous structures as little as possible.  Declare structure types
  191. like this (the _t on the type name is preferable but not required):
  192.  
  193.     typedef struct xxx_yyy_s {
  194.       ... members ...
  195.     } xxx_yyy_t;
  196.  
  197. Don't declare parameters as being of type float, short, or char.  If you do
  198. this and forget to include the prototype at a call site, ANSI compilers will
  199. generate incompatible calling sequences.  Use floatp (a synonym for double)
  200. instead of float, and use [u]int instead of short or char.
  201.  
  202. If you have a parameter that is itself a procedure, do list its parameter
  203. types rather than just using ().
  204.  
  205. Names
  206. -----
  207.  
  208. Use fully spelled-out English words in names rather than contractions.  This
  209. is most important for procedure and macro names, global variables and
  210. constants, #defined and enum values, structure and other typedef names, and
  211. structure member names, and for argument and variable names which have
  212. uninformative types like int.  It's not very important for arguments or
  213. local variables of distinctive types, or for local index or count variables.
  214.  
  215. Avoid names that run English words together.  hpgl_compute_arc_center is
  216. preferable to hpgl_compute_arccenter.
  217.  
  218. Procedures, variables, and structures visible outside a single .c file
  219. should generally have a prefix that indicates what subsystem they belong to
  220. (in the case of Ghostscript, gs_ or gx_).  This rule isn't followed very
  221. consistently.
  222.  
  223. Commenting
  224. ----------
  225.  
  226. The most important descriptive comments are ones in header files that
  227. describe structures, including invariants.  But every procedure or structure
  228. declaration, or group of other declarations, should have a comment.
  229.  
  230. Other formatting
  231. ----------------
  232.  
  233. Format procedures as follows:
  234.  
  235. scope return_type
  236. proc_name(type1 arg1, type2 arg2, type3 arg3, type4 verylongargument4,
  237.   type5 argument5)
  238. {    ... body ...
  239. }
  240.  
  241. Leave a blank line after the declarations of local variables in a procedure
  242. or compound statement, unless there's only 1 variable and the scope is less
  243. than 10 lines or so.
  244.  
  245. Other
  246. -----
  247.  
  248. When calling a variable or parameter procedure, do use explicit indirection,
  249. e.g., (*func)(...) rather than func(...).  It makes it clearer to the reader
  250. what is going on.  Also, not all compilers accept the elision.  (gcc accepts
  251. a dismaying number of constructs that other compilers dislike.)
  252.  
  253. ANSI compilers in their default mode do all floating point computations in
  254. double precision, so never cast a float to a double explicitly.
  255.  
  256. Unless there's a good reason for doing otherwise, return floatp (double)
  257. rather than float values.  Many FPUs do everything in double internally and
  258. have to do extra work to convert between double and float.
  259.  
  260. In general, don't create procedures that are private and only called from
  261. one place.  However, if a compound statement (especially an arm of a
  262. conditional) is long enough that the eye can't easily match up its } with
  263. its { (i.e., it's longer than 10 or 15 lines), and it doesn't use or set a
  264. lot of state held in outer local variables, putting it in a procedure may
  265. help readability.
  266.  
  267. Global variables
  268. ----------------
  269.  
  270. Avoid global variables (non-const data) like the plague.  Avoid global const
  271. data, but don't knock yourself out over it.
  272.  
  273. Local variables
  274. ---------------
  275.  
  276. Avoid assigning new values to procedure parameters.  It makes debugging very
  277. confusing when the parameter values printed for a procedure are not the ones
  278. actually supplied by the caller.  Instead, use a separate local variable
  279. that is initialized to the value of the parameter.
  280.  
  281. If a local variable only gets assigned a value once, assign it that value at
  282. its declaration, if convenient.  E.g.,
  283.  
  284.         int x = <some expression>;
  285.  
  286. rather than
  287.  
  288.         int x;
  289.         ...
  290.         x = <some expression>;
  291.  
  292. Error handling
  293. --------------
  294.  
  295. By convention, nearly all procedures return an int that indicates the
  296. outcome of the call: 0 indicates a normal return, >0 indicates a non-error
  297. return other than the normal case, and <0 indicates an error.  All callers
  298. should check for error returns and, in general, propagate them to *their*
  299. caller.
  300.  
  301. Preprocessor conditionals
  302. -------------------------
  303.  
  304. Conditionals can easily lead to unreadable code, since the eye really wants
  305. to read linearly rather than having to parse the conditionals just to figure
  306. out what code is relevant.  It's OK to use conditionals that have small
  307. scope and that don't change the structure or logic of the program
  308. (typically, they select between different sets of values depending on some
  309. configuration parameter), but where possible, break up source modules rather
  310. than use conditionals that affect the structure or logic.
  311.  
  312. Preprocessor macros
  313. -------------------
  314.  
  315. If you define a macro that looks like a procedure, make sure it will work
  316. wherever a procedure will work.  In particular, put parentheses around every
  317. use of a macro argument, so that the macro will parse correctly if some of
  318. the arguments are expressions.
  319.  
  320. PostScript code
  321. ===============
  322.  
  323. Put indentation points every 3 spaces.
  324.  
  325. Format procedure definitions like this:
  326.  
  327. /procname        % <arg1> <arg2> procname <result1> <result2>
  328.  { ...code...
  329.  } bind def
  330.